/**
 * 2017年10月23日
 */
package exp.algorithm.sic;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import org.slf4j.Logger;

import exp.algorithm.sic.feature.FeatureVector;
import exp.algorithm.sic.insts.FeatureVector2InstanceConverter;
import exp.algorithm.sic.insts.KMeansCentroidConverter;
import exp.core.InstancesLoader;
import exp.util.DatasetsUtil;
import weka.core.Instance;
import weka.core.Instances;

/**
 * @author Alex
 *
 */
public class SiftConverter implements Serializable{
	private static final long serialVersionUID = 1L;
	Logger log = org.slf4j.LoggerFactory.getLogger(SiftConverter.class);
	//里面每个元素是
	private List<InstanceFeatureVectors> instancesVectors = new ArrayList<>();
	private FeatureVector2InstanceConverter fic = new KMeansCentroidConverter(100);
	private int maxFeatureNum = -1;
	private int minFeatureNum = -1;
	PeakFinderType pft;
	VectorMakerType vmt;
	public int getmaxFeatureNum(){
		return maxFeatureNum;
	}
	public int getMinFeatureNum(){
		return minFeatureNum;
	}

	public SiftConverter(PeakFinderType pft,VectorMakerType vmt) {
		this.pft = pft;
		this.vmt = vmt;
	}

	public static InstanceFeatureVectors extractFeatureVector(Instance inst,PeakFinderType pft,VectorMakerType vmt){
		TimeSeries ts = TimeSeries.fromInstance(inst);
		Sifc sifc = new Sifc(pft,vmt);
		List<FeatureVector>  fvs = sifc.detectFeatures(ts);
		InstanceFeatureVectors isa = new InstanceFeatureVectors(fvs);
		isa.classValue = inst.classValue();
		return isa;
	}
	
	public static List<InstanceFeatureVectors> extractFeatureVector(Instances insts,PeakFinderType pft, VectorMakerType vmt,int[]minMax){
		//待转换数据的结构,只保留数据结构,不保存里面的数据
		//header = new Instances(insts,0);
		//将实例转换成TimeSeries
		List<TimeSeries> list = TimeSeries.fromInstance(insts);
		List<InstanceFeatureVectors> temp = new ArrayList<InstanceFeatureVectors>();
		//检测每个TimeSereis
		for(TimeSeries ts:list){
			Sifc sifc = new Sifc(pft,vmt);
			//一个实例中,最终检测到的特征向量
			List<FeatureVector> fvs = sifc.detectFeatures(ts);
			if(minMax!=null){
				if(fvs.size()<minMax[0]) minMax[0] = fvs.size();
				if(fvs.size()>minMax[1]) minMax[1] = fvs.size();
			}
			//将一个TimeSereis中的所有的octave中的所有的ScalePeak转换成InstanceStatisticsAtts实例
			InstanceFeatureVectors vecs = new InstanceFeatureVectors(fvs);
			vecs.classValue = ts.classVal;
			//保存InstanceStatisticsAtts以备后面使用
			temp.add(vecs);
		}
		List<InstanceFeatureVectors> res = removeZeroVectors(temp);
		return res;
	}
	public Instances transform(Instances insts){
		//待转换数据的结构,只保留数据结构,不保存里面的数据
		//header = new Instances(insts,0);
		//将实例转换成TimeSeries
		int[]res = new int[]{Integer.MAX_VALUE,Integer.MIN_VALUE};
		instancesVectors = extractFeatureVector(insts,this.pft,this.vmt,res);
		this.minFeatureNum = res[0];
		this.maxFeatureNum = res[1];
		fic.initialize(instancesVectors, insts);
		return fic.converteInstances(instancesVectors, insts);
	}
	public Instance transform(Instance f){
		return fic.converteInstance(extractFeatureVector(f, this.pft, this.vmt));
	}
	
	public InstanceFeatureVectors detectFeatureVectorsFromInstance(Instance inst){
		return extractFeatureVector(inst, this.pft, this.vmt);
	}
	
	private static List<InstanceFeatureVectors> removeZeroVectors(List<InstanceFeatureVectors>  vecs){
		return vecs.stream().filter(x->x.vecs.size()>0).collect(Collectors.toList());
	}
	public List<InstanceFeatureVectors> getInstanceVectors(){
		return instancesVectors;
	}
}
